package com.jy.bo.common.conf.util;

import com.fqgj.common.utils.MD5;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.*;

/**
 * Created with IntelliJ IDEA.
 * User: binary
 * Date: 2020/6/10
 * Time: 下午4:12
 */
public class SerialNumberUtil {

    /**
     * 自增id 6位
     */
    private static volatile long num = 1;

    private static String startTimeL3;

    private static String ipLastL3;

    static {
        String time = System.currentTimeMillis() + "";
        startTimeL3 = time.substring(time.length() - 3);

        String ip = null;
        try {
            ip = InetAddress.getLocalHost().getHostAddress();
        } catch (UnknownHostException e) {
        }
        if (ip == null) {
            ip = System.currentTimeMillis() + "";
        }

        String ipKey = MD5.md5(ip);
        ipLastL3 = ipKey.substring(ipKey.length() - 3);
    }

    /**
     * 生成默认流水号 28位 = 14位年月日时分秒+3位ip号+3位启动时间戳+2位类型+6位自增id
     *
     * @return
     */
    public static String getBizOrderNumber() {
        StringBuilder sb = new StringBuilder();
        int bitLength = 6;
        String number = String.valueOf(getId());
        String sequenceNoString = String.format("%0" + bitLength + "d", Long.parseLong(number.length() > bitLength ? number.substring(number.length() - bitLength) : number));
        sb.append(getDate(new Date(), "yyyyMMddHHmmss")).append(ipLastL3).append(startTimeL3).append("00").append(sequenceNoString);
        return sb.toString();
    }

    /**
     * 根据类型生成
     *
     * @param type1
     * @param type2
     * @return
     */
    public static String getBizOrderNumber(String type1, String type2) {
        String t1 = type1.substring(0, 1);
        String t2 = type2.substring(0, 1);
        StringBuilder sb = new StringBuilder();
        int bitLength = 6;
        String number = String.valueOf(getId());
        String sequenceNoString = String.format("%0" + bitLength + "d", Long.parseLong(number.length() > bitLength ? number.substring(number.length() - bitLength) : number));
        sb.append(getDate(new Date(), "yyyyMMddHHmmss")).append(ipLastL3).append(startTimeL3).append(t1).append(t2).append(sequenceNoString);
        return sb.toString();
    }

    private synchronized static long getId() {
        return num++;
    }

    private static String getDate(Date date, String pattern) {
        SimpleDateFormat df = null;
        String returnValue = "";
        if (date != null) {
            df = new SimpleDateFormat(pattern);
            returnValue = df.format(date);
        }
        return (returnValue);
    }

    public static void main(String[] args) {
        System.out.println(String.format("%03d", 0));
        System.out.println(String.format("%03d", 1));
        System.out.println(String.format("%03d", 255));
        System.out.println(getBizOrderNumber());
        System.out.println(getBizOrderNumber("A1", "A2"));

        ThreadPoolExecutor executor = new ThreadPoolExecutor(20, 20,
                200, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<Runnable>(100));


        System.out.println(getDate(new Date(), "yyyy-MM-dd HH:mm:ss"));

        long time = System.currentTimeMillis();

        num = 1;

        Map<String, Object> set = new ConcurrentHashMap();

        //经测试 获取200万个序列号 大约是14秒 获取一个id=0.007毫秒
        for (int i = 0; i < 10000; i++) {
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    String s1 = getBizOrderNumber();
                    String s2 = getBizOrderNumber("A", "B");
                    System.out.println(s1 + "," + s2);
                    set.put(s1, s1);
                    set.put(s2, s2);
                }
            };
            while (true) {
                try {
                    executor.submit(runnable);
                    break;//提交成功才break
                } catch (RejectedExecutionException e) {
                    try {
                        Thread.sleep(1);
                    } catch (Exception e1) {
                    }
                }
            }
        }
        executor.shutdown();
        try {
            executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
        } catch (InterruptedException e) {
        }

        long time2 = System.currentTimeMillis();

        System.out.println(getDate(new Date(), "yyyy-MM-dd HH:mm:ss"));
        System.out.println(time2 - time);
        System.out.println(num + ",set:" + set.size());
    }

}
